package de.fhin.mas.agents.manager.behaviours;

import jade.lang.acl.ACLMessage;
import jade.proto.AchieveREInitiator;

import java.util.Date;
import java.util.Vector;

import de.fhin.mas.MASEvents;
import de.fhin.mas.agents.manager.ManagerAgent;
import de.fhin.mas.ontology.Location;
import de.fhin.mas.util.MessageUtil;

/**
 * Initialisierung des abort_and_goto REQUESTS
 * 
 * @author Ast
 */
public class InitAbortAndGoto2 extends AchieveREInitiator {
	private static final long serialVersionUID = 1491783009463291627L;
	private ManagerAgent managerAgent;
	private Location location;

	/**
	 * Konstruktor
	 * 
	 * @param a
	 *            Der Agent.
	 * @param location
	 *            Das neu anzufahrende Ziel.
	 */
	public InitAbortAndGoto2(ManagerAgent a, Location location) {
		super(a, new ACLMessage(ACLMessage.REQUEST));
		this.managerAgent = a;
		this.location = location;
	}

	/**
	 * abort_and_goto-Request-Nachricht zusammenbauen.
	 */
	@Override
	protected Vector<ACLMessage> prepareRequests(ACLMessage request) {
		Vector<ACLMessage> msgs = new Vector<ACLMessage>(1);

		// Wir bauen einen Request
		ACLMessage msg = new ACLMessage(ACLMessage.REQUEST);
		msg.setProtocol(jade.domain.FIPANames.InteractionProtocol.FIPA_REQUEST);

		// Antwort wird innerhalb von 10 Sekunden erwartet
		msg.setReplyByDate(new Date(System.currentTimeMillis() + 10000));

		// Topic und Content
		MessageUtil.setMessageTopic(managerAgent, msg, MASEvents.ABORT_AND_GO_TO);
		managerAgent.fillMsgContent(msg, location);
		managerAgent.setAllAsReceivers(msg);

		managerAgent.printLn("SENDING: " + msg.getContent());
		Location loc = managerAgent.extractLocationFromMsg(msg);
		managerAgent.printLn("CHECK: " + loc.getDescription());

		msgs.addElement(msg);

		// Logging
		managerAgent.logInfo("abort_and_goto: request-messages prepared - sending...");

		return msgs;
	}

	@Override
	protected Vector prepareInitiations(ACLMessage initiation) {
		managerAgent.fillMsgContent(initiation, location);
		return super.prepareInitiations(initiation);
	}

	@Override
	protected void handleAllResponses(Vector responses) {
		managerAgent.logInfo(String.format("abort_and_goto: processing %d responses...", responses.size()));

		int aks = 0;
		for (int i = 0; i < responses.size(); i++) {
			ACLMessage msg = (ACLMessage) responses.get(i);
			if (msg.getPerformative() == ACLMessage.AGREE)
				aks++;
		}
	}

	/**
	 * Ergebnisse auswerten.
	 */
	@Override
	protected void handleAllResultNotifications(Vector resultNotifications) {
		managerAgent.logInfo(String.format("abort_and_goto: processing %d result notifications...", resultNotifications
				.size()));

		int dones = 0;
		for (int i = 0; i < resultNotifications.size(); i++) {
			ACLMessage msg = (ACLMessage) resultNotifications.get(i);
			if (msg.getPerformative() == ACLMessage.INFORM)
				dones++;
			if (msg.getPerformative() == ACLMessage.FAILURE) {
				dones = 0;
				break;
			}
		}

		// Falls Abbruch des Auftrags nicht möglich war,
		// dann alle anfordern, dass alle Aktoren sofort gestoppt werden
		// und Eingriff vom Benutzer fordern.

		// TODO: Nicht nur abzählen
		if (dones < 3)
			managerAgent.initSystemStop("FAILURE during abort_and_goto");
	}

}
